#include <bits/stdc++.h>
using namespace std;
#define int long long

int delts[4096] = {};
int t[4096][4096], a[4096][4096], n, q, op1[50005], dir[50005], i[50005], op2[50005], w[50005], alb[4096];
const int p = 999999999;
// 对于每一行，维护一个树状数组

inline void get_delt(int &x, int op, int w) {
	switch (op) {
		case 1: x &= w; return;
		case 2: x |= w; return;
		case 3: x ^= w; return;
	}
	(x += w) %= p;
}

inline void update_col(const int &c, const int &op, const int &w) { // 对一整列进行操作
	for (int r = 1; r <= n; ++r) {
		delts[r] = a[r][c];
		get_delt(a[r][c], op, w);
		delts[r] = -delts[r] + a[r][c];
	}
	for (int j = c; j <= n; j += (j & (-j))) {
		for (int r = 1; r <= n; ++r) {
			t[j][r] += delts[r];
		}
	}
}

inline void update_row(const int &r, const int &op, const int &w) {
	for (int c = 1; c <= n; ++c) {
		get_delt(a[r][c], op, w);
		t[c][r] = a[r][c];
	}
	for (int c = 1; c <= n; ++c) {
		t[alb[c]][r] += t[c][r];
	}
}

inline int query(int R, int C) {
	int ans = 0;
	while (C) {
		for (int r = 1; r <= R; ++r) ans += t[C][r];
		C -= (C & (-C));
	}
	return ans;
}

signed main() {
	freopen("fire.in", "r", stdin); freopen("fire.out", "w", stdout);
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> q;
	for (int i = 1; i <= n; ++i) {
		alb[i] = min(n + 1, i + (i & (-i)));
	}
	int dtot = 0;
	for (int _ = 1; _ <= q; ++_) {
		cin >> op1[_];
		if (op1[_] == 2) {
			cin >> i[_] >> w[_];
		} else {
			cin >> dir[_] >> i[_] >> op2[_] >> w[_];
			if (dir[_] == 1) {
				++dtot;
			} else {
				--dtot;
			}
		}
	}
	cerr << dtot << "\n";
	if (dtot <= 0) {
		for (int _ = 1; _ <= q; ++_) {
			if (op1[_] == 2) {
				swap(w[_], i[_]);
			} else {
				dir[_] ^= 1;
			}
		}
	}
	for (int _ = 1; _ <= q; ++_) {
		if (op1[_] == 2) {
			cout << query(i[_], w[_]) << "\n";
		} else {
			if (dir[_] == 0) update_row(i[_], op2[_], w[_]);
			else update_col(i[_], op2[_], w[_]);
		}
	}
}
